//
//  WLSocketWorker.m
//  WanLian
//
//  Created by 123456 on 2018/12/26.
//  Copyright © 2018 wanlian. All rights reserved.
//

#import "WLSocketWorker.h"
#import "GCDAsyncSocket.h"
#import "WLRecallModel.h"
#import "WLFileRequest.h"
#import "WLFileTransportHeadModel.h"
#import "LHYTimer.h"

static NSString *WLWorkerSocketQueueName = @"WLWorkerSocketQueueName";
BOOL flag = NO;//挂起标志
@interface WLSocketWorker ()<GCDAsyncSocketDelegate>

@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, assign) NSTimeInterval waitTime;
@end

@implementation WLSocketWorker
- (instancetype)init {
    if (self = [super init]) {
        workerSocketQueue = dispatch_queue_create([WLWorkerSocketQueueName UTF8String], NULL);
    }
    return self;
}
- (void)suspend {
    self.requestModel.workingState = WLWorkingStateSuspend;
    flag = YES;
    self.requestModel.bContinue = YES;
    [self.currentSocket disconnect];
//    self.currentSocket = nil;
    [self clearTimer];
    [self.parser stop];
}

- (void)cancel {
    self.requestModel.workingState = WLWorkingStateCanceal;
    flag = YES;
    [self.currentSocket disconnect];
    self.currentSocket = nil;
    [self clearTimer];
    [self.parser stop];
}

- (void)resume {
    flag = NO;
    WLWkSelf
    [self.currentSocket disconnect];
    [self connectWithFailBlock:^{
        weakSelf.requestModel.workingState = WLWorkingStateFail;
        if (weakSelf.recallModel.faliureBlock) {
            weakSelf.recallModel.faliureBlock(@"连接失败", FileTransportErrorTypeConnectFail);
        }
    }];
    [self.parser resume];
}

- (WLSocketWorker *)configWorkerWithFIFOModel:(WLFileRequest *)model
                         progress:(void (^)(float))progress
                          success:(void (^)(NSDictionary *successDict))success
                          failure:(void (^)(NSString *errorMsg, NSInteger errorTag))failure
                            error:(void (^)(NSError *error))err {return nil;}

- (WLSocketWorker *)configDownloadWorkerWithFIFOModel:(WLFileRequest *)model
                                             progress:(void (^)(float process, long expected, long loaded))progress
                                              success:(void (^)(NSDictionary *successDict))success
                                              failure:(void (^)(NSString *errorMsg, NSInteger errorTag))failure
                                                error:(void (^)(NSError *error))err {return nil;}

- (GCDAsyncSocket *)Client_init
{
    //创建socket
    GCDAsyncSocket *sock_fd = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:workerSocketQueue];
    self.currentSocket = sock_fd;
    return sock_fd;
}
- (NSData *)configHeadProtocolWithData:(NSData *)data {
    int protocolHead = 0x76;
    int version = 0x01;
    int type = 0x02;
    NSMutableData *muFileInfoData = [NSMutableData data];
    [muFileInfoData appendInt:protocolHead];
    [muFileInfoData appendInt:version];
    [muFileInfoData appendInt:type];
    [muFileInfoData appendData:data];
    return muFileInfoData;
}
- (void)clearTimer {
    self.waitTime = 0;
    
    [_timer invalidate];
    _timer = nil;
}
- (NSTimer *)timer {
    if (_timer == nil) {
//        _timer = [NSTimer timerWithTimeInterval:1.f target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
//        [[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
    }
//    [_timer fire];
    return _timer;
}
- (void)timerAction {
    
    WLWkSelf
//    dispatch_async(dispatch_get_main_queue(), ^{
        weakSelf.waitTime ++;
        if (weakSelf.waitTime >= self.requestModel.timeOut) {
            [weakSelf occorErrorWithMsg:@"数据请求失败，请稍后再试" errorNo:FileTransportRequestTimeOut];
            
            weakSelf.waitTime = 0;
            [weakSelf.timer invalidate];
        }
//    });
    
}
- (void)occorErrorWithMsg:(NSString *)errorMsg errorNo:(NSInteger)errorNum {
    if (self.fileTransportFailureBlock) {
        self.fileTransportFailureBlock(errorMsg, errorNum);
    } else if (self.recallModel.faliureBlock) {
        self.recallModel.faliureBlock(errorMsg, errorNum);
    }
}
#pragma mark - GCDAsyncSocketDelegate
/**
 * Called when a socket connects and is ready for reading and writing.
 * The host parameter will be an IP address, not a DNS name.
 **/
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port {
    self.waitTime = 0;
    [[self timer] fire];
}

/**
 * Called when a socket has completed reading the requested data into memory.
 * Not called if there is an error.
 **/
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    self.waitTime = 0;
}
/**
 * Called when a socket has completed writing the requested data. Not called if there is an error.
 **/
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {
    self.waitTime = 0;
}

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err {
    [self clearTimer];
    if (err) {
        [self occorErrorWithMsg:@"连接错误" errorNo:FileTransportErrorTypeConnectError];
    }
}

#pragma mark - 其他方法
- (void)connectWithFailBlock:(void (^)(void))failBlock {
    NSError *error = nil;
    BOOL suc = [self.currentSocket connectToHost:self.requestModel.host onPort:self.requestModel.port error:&error];
    self.requestModel.workingState = WLWorkingStateSending;
    if (error || !suc) {//连接失败
        if (failBlock) {
            failBlock();
        }
    }
}
- (void)dealloc {
    [self clearTimer];
}
@end
